package com.mazaiting.auth.security.extension.mobile;

import com.mazaiting.auth.constant.SecurityConst;
import com.mazaiting.auth.enums.GrantTypeEnum;
import com.mazaiting.auth.security.extension.base.BaseTokenGranter;
import com.mazaiting.common.core.constant.ExMessageConst;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.util.StringUtils;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 手机验证码授权者
 * 声明授权者 SmsCodeTokenGranter 支持授权模式 sms_code
 * 根据接口传值 grant_type = sms_code 的值匹配到此授权者
 * 匹配逻辑详见下面的两个方法
 *
 * @see CompositeTokenGranter#grant(String, TokenRequest)
 * @see AbstractTokenGranter#grant(String, TokenRequest)
 */
public class SmsCodeTokenGranter extends BaseTokenGranter {


    public SmsCodeTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService,
                               OAuth2RequestFactory requestFactory, AuthenticationManager authenticationManager) {
        super(tokenServices, clientDetailsService, requestFactory, GrantTypeEnum.SMS_CODE.getValue(), authenticationManager);
    }

    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        // 获取登录信息
        Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());

        // 获取手机号
        String mobile = parameters.get(SecurityConst.KEY_MOBILE);
        // 获取验证码
        String code = parameters.get(SecurityConst.KEY_CODE);
        // 移除无用参数
        parameters.remove(SecurityConst.KEY_CODE);
        // 判断手机号是否为空
        if (!StringUtils.hasLength(mobile)) {
            throw new InvalidGrantException(ExMessageConst.ERROR_PHONE_EMPTY);
        }

        // 判断验证码是否为空
        if (!StringUtils.hasLength(code)) {
            throw new InvalidGrantException(ExMessageConst.ERROR_VERIFY_CODE_NOT_EMPTY);
        }

        // 传入手机号与验证码
        AbstractAuthenticationToken userAuth = new SmsCodeAuthenticationToken(mobile, code);
        // 设置详细信息
        userAuth.setDetails(tokenRequest.getRequestParameters());

        return authenticate(client, tokenRequest, userAuth);
    }
}
